package com.beerandjesus.sportofkings.handicapper.model;

public enum RaceType {
    G1("Grade I"),
    G2("Grade II"),
    G3("Grade III"),
    N("Nongraded Stakes/Handicap"),
    A("Allowance"),
    R("Starter Allowance"),
    T("Starter Handicap"),
    C("Claiming"),
    CO("Optional Claiming"),
    S("Maiden Special Weight"),
    M("Maiden Claiming"),
    AO("Allowance Optional Claiming"),
    MO("Maiden Optional Claiming"),
    NO("Optional Claiming Stakes"),
    EMPTY("Empty"),
    UNDEFINED("Undefined");
    private String name;

    private RaceType(String name) {
        this.name = name;
    }

    public String getDescription() {
        return name;
    }

    public boolean isMaiden() {
        switch (this) {
            case S:
            case M:
            case MO:
                return true;
        }
        return false;
    }

    /**
     * Determine whether this race type represents a drop in class
     * from a previous race type, for use in testing for a drop in
     * class combined with a favorable jockey switch, per the system
     * developed by Mark Cramer.
     *
     * @param claimingPrice             Claiming price of the current race, if any
     * @param previousRace              The previous race's race type
     * @param previousRaceClaimingPrice Claiming price of the previous race, if any
     * @return True if it is determined that there is a drop in class,
     * false otherwise.
     */
    public boolean isCramerClassDrop(Integer claimingPrice, RaceType previousRace, Integer previousRaceClaimingPrice) {
        if (previousRace == null || previousRace.equals(EMPTY) || previousRace.equals(UNDEFINED)) {
            return false;
        }
        switch (this) {
            case EMPTY:
            case UNDEFINED:
            case G1:
            case G2:
            case G3:
                return false;
            case N:
            case NO:
                switch (previousRace) {
                    case G1:
                    case G2:
                    case G3:
                        return true;
                    default:
                        return false;
                }
            case A:
            case R:
                switch (previousRace) {
                    case G1:
                    case G2:
                    case G3:
                    case N:
                    case NO:
                        return true;
                    default:
                        return false;
                }
            case T:
                switch (previousRace) {
                    case G1:
                    case G2:
                    case G3:
                    case N:
                    case NO:
                    case A:
                    case R:
                        return true;
                    default:
                        return false;
                }
            case S:
                switch (previousRace) {
                    case G1:
                    case G2:
                    case G3:
                    case N:
                    case NO:
                    case A:
                    case R:
                    case T:
                        return true;
                    default:
                        return false;
                }
        }
        // Current race is a claiming race
        switch (previousRace) {
            case G1:
            case G2:
            case G3:
            case N:
            case NO:
            case A:
            case R:
            case T:
            case S:
                return true;
        }
        return claimingPrice != null && (previousRaceClaimingPrice == null || (claimingPrice < previousRaceClaimingPrice));
    }

    public boolean isCramerClassDrop(RaceType previousRace) {
        return isCramerClassDrop(null, previousRace, null);
    }


    public static boolean isDropFromAllowanceTo40KClaiming(RaceType previous, RaceType current, String currentPurse) {
        int purse;
        try {
            purse = Integer.valueOf(currentPurse);
        } catch (NumberFormatException e) {
            return false;
        }
        return (previous != null && current != null
                && previous.isAllowance() && current.isClaiming() && purse < 40000);
    }

    public boolean isClaiming() {
        switch (this) {
            case C:
            case CO:
            case M:
                return true;
            default:
                return false;
        }
    }

    private boolean isAllowance() {
        return this.equals(A);
    }
}
